package com.gitee.wsl.prism4j.languages

import com.gitee.wsl.ext.or
import com.gitee.wsl.prism4j.Prism4j
import com.gitee.wsl.prism4j.Prism4j.Companion.grammar
import com.gitee.wsl.prism4j.Prism4j.Companion.pattern
import com.gitee.wsl.prism4j.Prism4j.Companion.token
import com.gitee.wsl.prism4j.Prism4j.Pattern

@Suppress("unused")
object Prism_yaml {
    fun create(prism4j: Prism4j): Prism4j.Grammar {
        return grammar(
            "yaml",
            token(
                "scalar", pattern(
                    Pattern.compile("([\\-:]\\s*(?:![^\\s]+)?[ \\t]*[|>])[ \\t]*(?:((?:\\r?\\n|\\r)[ \\t]+)[^\\r\\n]+(?:\\2[^\\r\\n]+)*)"),
                    true,
                    false,
                    "string"
                )
            ),
            token("comment", pattern(Pattern.compile("#.*"))),
            token(
                "key", pattern(
                    Pattern.compile("(\\s*(?:^|[:\\-,\\[{\\r\\n?])[ \\t]*(?:![^\\s]+)?[ \\t]*)[^\\r\\n{\\[\\]},#\\s]+?(?=\\s*:\\s)"),
                    true,
                    false,
                    "atrule"
                )
            ),
            token(
                "directive", pattern(
                    Pattern.compile("(^[ \\t]*)%.+", Pattern.MULTILINE),
                    true,
                    false,
                    "important"
                )
            ),
            token(
                "datetime", pattern(
                    Pattern.compile(
                        "([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(?:\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \\t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \\t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?)(?=[ \\t]*(?:$|,|]|\\}))",
                        Pattern.MULTILINE
                    ),
                    true,
                    false,
                    "number"
                )
            ),
            token(
                "boolean", pattern(
                    Pattern.compile(
                        "([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(?:true|false)[ \\t]*(?=$|,|]|\\})",
                        Pattern.MULTILINE or Pattern.CASE_INSENSITIVE
                    ),
                    true,
                    false,
                    "important"
                )
            ),
            token(
                "null", pattern(
                    Pattern.compile(
                        "([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(?:null|~)[ \\t]*(?=$|,|]|\\})",
                        Pattern.MULTILINE or Pattern.CASE_INSENSITIVE
                    ),
                    true,
                    false,
                    "important"
                )
            ),
            token(
                "string", pattern(
                    Pattern.compile(
                        "([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)(\"|')(?:(?!\\2)[^\\\\\\r\\n]|\\\\.)*\\2(?=[ \\t]*(?:$|,|]|\\}))",
                        Pattern.MULTILINE
                    ),
                    true,
                    true
                )
            ),
            token(
                "number", pattern(
                    Pattern.compile(
                        "([:\\-,\\[{]\\s*(?:![^\\s]+)?[ \\t]*)[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)[ \\t]*(?=$|,|]|\\})",
                        Pattern.MULTILINE or Pattern.CASE_INSENSITIVE
                    ),
                    true
                )
            ),
            token("tag", pattern(Pattern.compile("![^\\s]+"))),
            token("important", pattern(Pattern.compile("[&*][\\w]+"))),
            token("punctuation", pattern(Pattern.compile("---|[:\\[\\]{}\\-,|>?]|\\.\\.\\.")))
        )
    }
}
